【JavaScript】イミュータブル・ミュータブル - 値の変更可否

【JavaScript】イミュータブル・ミュータブル - 値の変更可否

JavaScriptのイミュータブルとミュータブルについて解説します。

検証環境

値の変更可否

値には変更不可な値と変更可能な値があります。

変更不可を『イミュータブル』、変更可能を『ミュータブル』と呼びます。

意図したプログラムを組むには、この性質を理解することが重要です。

イミュータブル

イミュータブルな値は“変更不可な値”です。

代表的な値は数値や文字列などがあります。

次のコードで具体的なイメージを示します。

let num = 1;

console.log(num);

num = 8;

console.log(num);
1
8

変数numの値を8から10に変更しました。

一見値を変更できたように見えますが、内部的なイメージは新しい記憶領域に10を格納し、変数と紐づいたイメージです。

ミュータブル

ミュータブルな値は“変更可能な値”です。

代表的な値はArrayオブジェクト(配列)やObjectオブジェクトがあります。

次のコードで具体的なイメージを示します。

let data = [ 1, 2, 3 ];

console.log(data);

data[0] = 0;

console.log(data);
(4) [1, 2, 3]
(4) [0, 2, 3]

変数dataの配列の値を変更しました。

内部的なイメージは記憶領域の値を変更したイメージです。

動作の違い

値がイミュータブルとミュータブルのどちらかによって動作が変わる場合があります。

各コードを比較すると動作の違いが分かります。

先ずはイミュータブルな値の検証コードをご覧ください。

let x = 1;

let y = x;

y = 8;

console.log(x);
console.log(y);
1
8

変数xの値を変数yに代入し、その後、変数yの値を変更しています。

変数xの値は変数yの変更の影響を受けず1のままです。

しかし、ミュータブルな値は影響を受けます。

let x = [ 1, 2, 3 ];

let y = x;

y[0] = 0;

console.log(x);
console.log(y);
(3) [0, 2, 3]
(3) [0, 2, 3]

変数yの値を変更すると、変数xの値も同様に変わりました。

配列はミュータブルな値のため、内部的に記憶領域の値が変更されたためになります。

※ 変数xyは同じ記憶領域に紐づいているイメージです。

引数の影響

前項で説明した内容は引数においても同様です。

イミュータブルな値は呼び出し元に影響はありませんが、ミュータブルな値は呼び出し元に影響します。

先ずはイミュータブルな値を確認します。

function test( y ) {
    y = 8;
    console.log(y);
}

let x = 1;

test(x);

console.log(x);
8
1

関数の処理で仮引数の値を変更しています。

実行結果から実引数xの値は変わっておらず、影響していないことが分かります。

次にミュータブルな値を確認します。

function test( y ) {
    y[0] = 0;
    console.log(y);
}

let x = [ 1, 2, 3 ];

test(x);

console.log(x);
(3) [0, 2, 3]
(3) [0, 2, 3]

関数の処理で仮引数の値を変更しています。

実行結果から実引数xの値も変わっていることが分かります。


このように値はイミュータブルかミュータブルで動作が変わります。

意図した処理を行うにはこの性質を理解してプログラミングする必要があります。